/* Analisador Lexico 
 * 
 * UFCG - DSC - Compiladores 2010.1

 * Autores::
 * 	Daniel Lucena
 * 	Danilo Queiroz
*/

%{
#include <stdio.h>
#include <string.h>
#include "tkvalues.h"
int yylex(void); // funcao do lexico para retornar o token
int yyerror(char *msg); // funcao de erro (sobescrita)
int line = 1; // declarado no lexico
int col = 0;  // declarado no lexico
char* yytext = ""; // declarado no lexico
%}

%union {
	char* strval;
}


%token DPT PT VIRGULA BARRA SETA CONT INV IF THEN ELSE ENDIF NOT MINUS PLUS MULT DIV APAREN FPAREN 
%token <strval> COLOP
%token <strval> COLOPSIZE
%token <strval> RELOP
%token <strval> LOGOP
%token <strval> ID 
%token <strval> INT
%token <strval> FLOAT
%token <strval> STRING

%type <strval> nomeDecl typeSpec unaOp propCall literalId literalNum literalString addOp multiOp declarator 

%%

arquivo:	contexto arquivo 
 	| 	/* vazio */
	;
contexto:	CONT ID {printf("_GC::%d,%d::%s\n",line,col,$2);printf("VRT::%d,%d::%s\n",line,col,$2); printf("STC::%d,%d::%s\n",line,col,$2);} invariantes 
	|	CONT ID {printf("_GC::%d,%d::%s\n",line,col,$2);printf("VRT::%d,%d::%s\n",line,col,$2); printf("STC::%d,%d::%s\n",line,col,$2);} DPT ID invariantes
	;
invariantes:	invariante {printf("RSP::%d,%d::\n",line,col);} exprOCL {printf("_FI::%d,%d::\n",line,col);} invariantes
	| 	/* vazio */
	;
invariante:	INV DPT {printf("_GI::%d,%d::invarianteN\n",line,col);}
	| 	INV ID DPT{printf("_GI::%d,%d::%s\n",line,col,$2);}
	;
exprOCL:	{printf("_MK::%d,%d::\n",line,col);}exprLog; 
exprLog:	exprRel {printf("_RM::%d,%d::\n",line,col);}  
	|	exprRel LOGOP {printf("_LP::%d,%d::%s\n",line,col,$2);} exprLog {printf("_VI::%d,%d::\n",line,col);printf("VOB::%d,%d::\n",line,col);} 
;
exprRel:	exprAdit
	|	exprAdit RELOP {printf("_CA::%d,%d::%s\n",line,col,$2);} exprRel {printf("VOR::%d,%d::\n",line,col);}
	;
exprAdit:	exprMult
	|	exprMult addOp {printf("_CA::%d,%d::%s\n",line,col,$2);} exprAdit {printf("VON::%d,%d::\n",line,col);} 
	;
addOp:		PLUS {$$="+";}| MINUS {$$="-";};
exprMult: 	exprUna
	|	exprUna multiOp {printf("_CA::%d,%d::%s\n",line,col,$2);} exprMult {printf("VON\%d,%d::\n",line,col);}
	;
multiOp: 	MULT {$$="*";}| DIV {$$="/";};
exprUna:	{printf("CRP::%d,%d::\n",line,col);printf("_MK::%d,%d::\n",line,col);}exprPrima exprProp{printf("_RM::%d,%d::\n",line,col);}
	|	unaOp {printf("_CA::%d,%d::%s\n",line,col,$1); printf("_MK::%d,%d::\n",line,col);printf("CRP::%d,%d::\n",line,col);}exprPrima exprProp{printf("_RM::%d,%d::\n",line,col);printf("VOU::%d,%d::%s\n",line,col,$1);};
unaOp: 		NOT {$$="!";}| MINUS {$$="-";};
exprProp:	PT{printf("_CA::%d,%d::.\n",line,col);} propCall exprProp 
	|	SETA{printf("VCO::%d,%d::\n",line,col);} collecCall exprProp
	| 	/* vazio */
	;
exprPrima:	literalString {printf("_CA::%d,%d::%s\n",line,col,$1);}	
	|	literalNum {printf("_CA::%d,%d::%s\n",line,col,$1);}
	|	propCall 
	|	APAREN {printf("_CA::%d,%d::(\n",line,col);} exprOCL FPAREN{printf("_CA::%d,%d::)\n",line,col);} 
	| 	exprIf 
	; 			
collecCall:	COLOP{printf("_SC::%d,%d::\n",line,col);}collecParams {printf("PRC::%d,%d::%s\n", line, col, $1);printf("_CC::%d,%d::%s\n",line,col,$1);printf("RTP::%d,%d::\n",line,col);}
	|	COLOPSIZE APAREN FPAREN {printf("_CA::%d,%d::.length\n",line,col);printf("PRC::%d,%d::%s\n", line, col, $1);}
	;
collecParams:	APAREN declarator {printf("_MK::%d,%d::#\n",line,col);}exprOCL {printf("_RM::%d,%d::#\n",line,col);printf("_SD::%d,%d::%s\n",line,col,$2);}FPAREN;
literalId:	ID {printf("VRI::%d,%d::%s\n",line,col,$1);printf("PID::%d,%d::%s\n",line,col,$1); $$=$1;};
literalString:	STRING{printf("PST::%d,%d::%s\n",line,col,$1); $$=$1;};
literalNum: 	FLOAT {printf("PFT::%d,%d::%s\n",line,col,$1); $$=$1;}
	| 	INT {printf("PIN::%d,%d::%s\n",line,col,$1); $$=$1;};
propCall:	literalId {printf("_CA::%d,%d::%s\n",line,col,$1);}
	|	literalId {printf("_CA::%d,%d::%s\n",line,col,$1);} callParams 
	;
exprIf:		IF{printf("_CA::%d,%d::((\n",line,col);} exprOCL {printf("_CA::%d,%d::)?(\n",line,col);}THEN exprOCL {printf("_CA::%d,%d::):(\n",line,col);}ELSE exprOCL {printf("_CA::%d,%d::))\n",line,col);}ENDIF 
callParams:	APAREN {printf("_CA::%d,%d::(\n",line,col);} paramList {printf("_CA::%d,%d::)\n",line,col);printf("VNP::%d,%d::\n",line,col);}FPAREN;
paramList: 	exprOCL{printf("VRP::%d,%d::\n",line,col);}
	|	exprOCL{printf("VRP::%d,%d::\n",line,col);printf("_CA::%d,%d::,\n",line,col);} VIRGULA paramList
	|	/* vazio */
	;
declarator:	BARRA nomeDecl typeSpec BARRA {$$=$2; printf("DCL::%d,%d::%s %s\n",line,col,$2,$3);};
nomeDecl:	ID {$$=$1;};
typeSpec:	DPT ID {$$=$2;}
	| 	{$$="nondecl";}/* vazio */
	;
		

%%

int main(void) {
	yydebug=0;
	return yyparse();
}

int yyerror(char *msg){
	// funcao de erro - imprime linha e coluna do erro sintatico
	int tk = YYTRANSLATE(yychar);
	if ( strcmp("syntax error", msg) == 0) {
		msg = "Erro Sintático";
	}
	fprintf(stderr,"%s::\n",msg);
	fprintf(stderr,"\tLinha %d, Coluna %d\n", line, col);
	fprintf(stderr,"\tUltimo token lido: %s - %s\n",yytname[tk], yytext);
	return 1;	
}

